package com.zhaorujie.rpc.core.remoting.netty.client;

import com.zhaorujie.rpc.core.remoting.invoker.RpcInvokerFactory;
import com.zhaorujie.rpc.core.remoting.params.Beat;
import com.zhaorujie.rpc.core.remoting.params.RpcResponse;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.timeout.IdleStateEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author 赵汝杰
 * @version v1.0
 * @description NettyClientHandler
 * @date 2024/3/11
 **/
public class NettyClientHandler extends SimpleChannelInboundHandler<RpcResponse> {

    private final static Logger logger = LoggerFactory.getLogger(NettyClientHandler.class);

    private RpcInvokerFactory rpcInvokerFactory;



    public NettyClientHandler(RpcInvokerFactory rpcInvokerFactory) {
        this.rpcInvokerFactory = rpcInvokerFactory;
    }


    @Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, RpcResponse rpcResponse) throws Exception {
        rpcInvokerFactory.notifyInvokerFuture(rpcResponse.getRequestId(), rpcResponse);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        logger.error("xxl-rpc netty client caught exception", cause);
        ctx.close();
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        if (evt instanceof IdleStateEvent){
            ctx.writeAndFlush(Beat.RPC_REQUEST);
            logger.debug("xxl-rpc netty client send beat-ping.");
        } else {
            super.userEventTriggered(ctx, evt);
        }
    }
}
